package com.system.arrangement.service.impl;

import com.system.arrangement.been.*;
import com.system.arrangement.dto.ArrangementDTO;
import com.system.arrangement.feign.*;
import com.system.arrangement.repository.ArrangementRepository;
import com.system.arrangement.service.*;
import com.system.arrangement.vo.ArrangementManageVO;
import com.system.arrangement.vo.ArrangementVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author 林
 */
@Service
public class ArrangementServiceImpl implements ArrangementService {

    @Autowired
    private ArrangementRepository arrangementRepository;

    @Autowired
    private EmployeeServiceFeign employeeServiceFeign;

    @Autowired
    private BusinessServiceFeign businessServiceFeign;
    @Autowired
    private DepartServiceFeign departServiceFeign;
    @Autowired
    private ConsultationRoomFeign consultationRoomFeign;

    @Autowired
    private RegistrationPoolListServiceFeign registrationPoolListServiceFeign;
    @Autowired
    private Builder builder;
    @Autowired
    public ArrangementServiceImpl(Builder builder) {
        this.builder = builder;
    }

    @Override
    public Integer saveArrangement(Arrangement arrangement) {
        Arrangement obj = arrangementRepository.save(arrangement);
        return obj.getArrangementId();
    }

    @Override
    public boolean removeArrangementById(int id) {
        if (arrangementRepository.existsById(id)) {
            arrangementRepository.deleteById(id);
            return true;
        }
        return false;
    }

    @Override
    public boolean modifyArrangement(Arrangement arrangement) {
        Arrangement obj = arrangementRepository.save(arrangement);
        if(obj != null){
            return true;
        }
        return false;
    }

    @Override
    public Arrangement getArrangementById(int id) {
        if (arrangementRepository.existsById(id)) {
            return arrangementRepository.getReferenceById(id);
        }
        return null;
    }

    @Override
    public List<Arrangement> listAllArrangements() {
        return arrangementRepository.findAll();
    }

    @Override
    public List<Arrangement> listByDt(LocalDate arrangementDt) {
        return arrangementRepository.findAllByArrangementDt(arrangementDt);
    }

    @Override
    public List<Arrangement> findAllByEmployeeIdAndArrangementDt(int employeeId, LocalDate arrangementDt) {
        return arrangementRepository.findAllByEmployeeIdAndArrangementDt(employeeId,arrangementDt);
    }
    @Override
    public List<ArrangementVO> findAllByDepartmentIdAndArrangementDt(int departmentId, LocalDate arrangementDt) {
        List<Employee> employees = employeeServiceFeign.listAllByDepartmentId(departmentId);
        List<Arrangement> allArrangements = new ArrayList<>();
        List<RegistrationPoolList> allRegistrationPoolLists = new ArrayList<>();
        List<ArrangementVO> arrangementVOList = new ArrayList<>();

        for (Employee employee : employees) {
            int employeeId = employee.getEmployeeId();
            List<Arrangement> arrangements = findAllByEmployeeIdAndArrangementDt(employeeId, arrangementDt);
            allArrangements.addAll(arrangements);
        }

        for(Arrangement arrangement : allArrangements){
            int arrangementId = arrangement.getArrangementId();
            List<RegistrationPoolList> registrationPoolLists = registrationPoolListServiceFeign.findAllByArrangementId(arrangementId);
            allRegistrationPoolLists.addAll(registrationPoolLists);
        }

        for (Arrangement allArrangement : allArrangements) {
            ArrangementVO arrangementVO = new ArrangementVO();
            arrangementVO.setArrangementId(allArrangement.getArrangementId());
            arrangementVO.setBusinessId(allArrangement.getBusinessId());
            Employee employee = employeeServiceFeign.getHandle(allArrangement.getEmployeeId());
            arrangementVO.setEName(employee.getEName());
            arrangementVO.setEType(employee.getEType());
            arrangementVO.setArrangementDt(allArrangement.getArrangementDt());
            arrangementVO.setPhoto(employee.getPhoto());
            arrangementVO.setLockNum(registrationPoolListServiceFeign.findLockNumByArrangementId(allArrangement.getArrangementId()));
            arrangementVO.setETitle(employee.getETitle());
            arrangementVO.setRegistrationNum(registrationPoolListServiceFeign.findNumByArrangementId(allArrangement.getArrangementId()));
            arrangementVO.setRegistrationPrice(allRegistrationPoolLists.get(0).getRegistrationPrice());
            arrangementVO.setPost(employee.getPost());
            List<RegistrationPoolList> registrationPoolLists = registrationPoolListServiceFeign.findAllByArrangementId(allArrangement.getArrangementId());
            if("8:00".equals(registrationPoolLists.get(0).getBgnTm())&& "17:00".equals(registrationPoolLists.get(registrationPoolLists.size()-1).getEndTm())){
                arrangementVO.setWorkTime("全天");
            }else if("8:00".equals(registrationPoolLists.get(0).getBgnTm())){
                arrangementVO.setWorkTime("上午");
            }else{
                arrangementVO.setWorkTime("下午");
            }
            arrangementVOList.add(arrangementVO);
        }

        return arrangementVOList;
    }

    @Override
    public List<String> stateByDt(int departmentId, LocalDate arrangementDt) {
        List<String> stateList = new ArrayList<>();
        for (int i = 0; i < 7; i++) { // 查询一周的状态，从当前日期往后推六天
            List<ArrangementVO> arrangementVOList = findAllByDepartmentIdAndArrangementDt(departmentId, arrangementDt.plusDays(i));
            Context context = new Context();
            if (arrangementVOList.size() == 0) {
                NoExistNumberState startState = new NoExistNumberState();
                startState.doAction(context);
                stateList.add(context.getState().toString());
            } else {
                boolean hasNumber = false;
                for (ArrangementVO arrangementVO : arrangementVOList) {
                    if (!Objects.equals(arrangementVO.getLockNum(), arrangementVO.getRegistrationNum())) {
                        IsExistNumberState startState = new IsExistNumberState();
                        startState.doAction(context);
                        stateList.add(context.getState().toString());
                        hasNumber = true;
                        break;
                    }
                }
                if (!hasNumber) {
                    FullNumberState startState = new FullNumberState();
                    startState.doAction(context);
                    stateList.add(context.getState().toString());
                }
            }

        }
        return stateList;
    }

    @Override
    public Integer addNewArrangement(ArrangementDTO arrangementDTO) {
        Arrangement arrangement = new Arrangement();
        arrangement.setArrangementDt(arrangementDTO.getArrangementDt());
        arrangement.setBusinessId(arrangementDTO.getBusinessId());
        Business business = businessServiceFeign.getHandle(arrangementDTO.getBusinessId());
        IntervalPlan intervalPlan = businessServiceFeign.getIntervalPlanHandle(business.getIntervalPlanId());
        arrangement.setBgnTm(intervalPlan.getBgnTm());
        arrangement.setEndTm(intervalPlan.getEndTm());
        arrangement.setConsultationId(arrangementDTO.getConsultationId());
        Subject subject = new Subject();
        new BinaryObserver(subject);
        int poolId = registrationPoolListServiceFeign.saveHandle(subject.setArrangementDTO(arrangementDTO));
        arrangement.setPoolId(poolId);
        arrangement.setEmployeeId(arrangementDTO.getEmployeeId());
        int arrangementId = saveArrangement(arrangement);


        List<IntervalPlanLst> intervalPlanLsts = businessServiceFeign.findAllByIntervalPlanId(intervalPlan.getIntervalPlanId());
        for (IntervalPlanLst intervalPlanLst : intervalPlanLsts) {
            builder.buildEndTm(intervalPlanLst.getEndTm());
            builder.buildArrangementId(arrangementId);
            builder.buildPoolId(poolId);
            builder.buildRegistrationNum(intervalPlanLst.getRegistrationNum());
            builder.buildRegistrationPrice(business.getRegistrationPrice());
            builder.buildBgnTm(intervalPlanLst.getBgnTm());
            builder.buildAddNum();
            builder.buildLockNum();
            registrationPoolListServiceFeign.saveHandle(builder.getResult());
        }
        return arrangementId;
    }

    @Override
    public List<ArrangementManageVO> findAllArrangementManageVO() {
        List<Arrangement> arrangements = listAllArrangements();
        List<ArrangementManageVO> arrangementManageVOS = new ArrayList<>();
        for (Arrangement arrangement : arrangements) {
            ArrangementManageVO arrangementManageVO = new ArrangementManageVO();
            arrangementManageVO.setArrangementDt(arrangement.getArrangementDt().toString());
            arrangementManageVO.setArrangementId(arrangement.getArrangementId());
            arrangementManageVO.setBgnTm(arrangement.getBgnTm());
            arrangementManageVO.setEndTm(arrangement.getEndTm());
            Employee employee = employeeServiceFeign.getHandle(arrangement.getEmployeeId());
            String departName = departServiceFeign.getDepartName(employee.getDepartmentId());
            ConsultationRoom consultationRoom = consultationRoomFeign.getHandle(arrangement.getConsultationId());
            Business business = businessServiceFeign.getHandle(arrangement.getBusinessId());
            arrangementManageVO.setCrName(consultationRoom.getCrName());
            arrangementManageVO.setBusinessName(business.getBusinessName());
            arrangementManageVO.setDepartmentName(departName);
            arrangementManageVO.setEmployeeName(employee.getEName());
            arrangementManageVOS.add(arrangementManageVO);
        }
        Collections.reverse(arrangementManageVOS);
        return arrangementManageVOS;

    }
}
